import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:film/controller/auth_controller.dart';
import 'package:film/controller/film_category_controller.dart';
import 'package:film/controller/home_controller.dart';
import 'package:film/model/film_category_model.dart';
import 'package:film/model/film_model.dart';
import 'package:film/screen/top_arc_border.dart';
import 'package:film/service/api_service.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class HomeScreen extends StatefulWidget {
  HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  final FilmCategoryController filmCategoryController = Get.put(FilmCategoryController());
  final HomeController homeController = Get.put(HomeController());
  final DioService apiService = DioService();
  final AuthController authController = Get.find();
  late EasyRefreshController _controller;

  int _currentIndex = 0;
  final List<String> imageUrls = [
    'assets/images/all.png',
    'assets/images/top.png',
  ];

  @override
  void initState() {
    super.initState();
    _tabController = TabController(
      length: 5,
      vsync: this,
    );
    _tabController.addListener(_handleTabChange);
    _controller = EasyRefreshController(
      controlFinishRefresh: true,
      controlFinishLoad: true,
    );
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  void _handleTabChange() {
    if (_tabController.index != _tabController.previousIndex) {
      if (_tabController.index != 0) {
        filmCategoryController.selectFilterOption('type_id', filmCategoryController.options[_tabController.index]);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: const BoxDecoration(
          color: Colors.white,
        ),
        child: Column(
          children: [
            // 顶部搜索栏
            SizedBox(height: MediaQuery.of(context).padding.top),
            _buildSearchBar(),
            SizedBox(height: 5),
            // TabBar
            Container(
              height: 40,
              color: Colors.yellow,
              alignment: Alignment.centerLeft,
              child: TabBar(
                controller: _tabController,
                isScrollable: true,
                labelColor: Colors.red,
                unselectedLabelColor: Colors.grey,
                indicatorSize: TabBarIndicatorSize.label,
                indicatorWeight: 0.0,
                padding: const EdgeInsets.only(bottom: 5.0),
                labelPadding: const EdgeInsets.only(bottom: 2.0, left: 10.0, right: 10.0, top: 2),
                dividerHeight: 0,
                indicator: ShapeDecoration(
                  shape: TopArcBorder(
                    borderColor: Colors.red,
                    borderWidth: 2.0,
                    arcWidth: 10.0,
                  ),
                ),
                tabAlignment: TabAlignment.start,
                tabs: List.generate(
                  5, // 5个Tab
                  (index) {
                    return Tab(
                      child: AnimatedBuilder(
                        animation: _tabController.animation!,
                        builder: (context, child) {
                          // 获取当前Tab的动画进度（0.0~1.0）
                          final double animationValue = _tabController.animation!.value;
                          final double selectedness = Curves.easeOut.transform(
                            (index == animationValue.floor() || index == animationValue.ceil()) ? (1.0 - (animationValue - index).abs()) : 0.0,
                          );
                          // 缩放比例：未选中时0.9，选中时1.0
                          final double scale = 0.8 + selectedness * 0.1;
                          return Transform.scale(
                            scale: scale,
                            alignment: Alignment.center, // 从中心点缩放
                            child: child,
                          );
                        },
                        child: Container(
                          width: 50,
                          height: 22,
                          alignment: Alignment.center,
                          child: Text(
                            ['推荐', '番剧', '剧场版', '4K', '待添加'][index],
                            style: const TextStyle(
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    );
                  },
                ),
              ),
              // ),
            ),

            // TabBarView内容区
            Expanded(
              child: TabBarView(
                controller: _tabController,
                children: [
                  _buildTabHome(),
                  _buildTabContent('新番日漫内容'),
                  _buildTabContent('新番国漫内容'),
                  _buildTabContent('动漫番剧内容'),
                  _buildTabContent('剧场动漫内容'),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildSearchBar() {
    return Row(
      children: [
        const SizedBox(width: 5),
        ClipRRect(
          borderRadius: BorderRadius.circular(5), // 圆角半径设为宽度的一半
          child: Image.asset(
            'assets/images/head.png',
            width: 30,
            height: 30,
            fit: BoxFit.cover, // 确保图片填充整个区域
          ),
        ),
        const SizedBox(width: 5),
        Expanded(
          child: GestureDetector(
            onTap: () {
              Get.toNamed('/filmSearch');
            },
            child: Container(
              height: 40,
              decoration: BoxDecoration(
                color: Colors.grey[200],
                borderRadius: BorderRadius.circular(50),
              ),
              child: const Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Padding(
                    padding: EdgeInsets.only(left: 12),
                    child: Icon(
                      Icons.search,
                      size: 16,
                      color: Colors.grey,
                    ),
                  ),
                  SizedBox(width: 5),
                  Text(
                    '搜索',
                    style: TextStyle(
                      fontSize: 12,
                      color: Colors.grey,
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
        const SizedBox(width: 5),
        GestureDetector(
          onTap: () => authController.checkToken('/playRecord'),
          child: const Icon(
            Icons.history,
            size: 25,
            color: Colors.grey,
          ),
        ),
        const SizedBox(width: 5),
      ],
    );
  }

  Widget _buildTabHome() {
    return SingleChildScrollView(
      child: Container(
        child: Column(
          children: [
            SizedBox(height: 10),
            Stack(
              alignment: Alignment.bottomRight,
              children: [
                Obx(
                  () => CarouselSlider(
                    options: CarouselOptions(
                      height: 200,
                      viewportFraction: 1.0,
                      autoPlay: true,
                      autoPlayInterval: Duration(seconds: 3),
                    ),
                    items: homeController.carouselFilmList.map((film) {
                      return GestureDetector(
                        onTap: () async {
                          bool isLogin = await authController.check();
                          if (isLogin) {
                            String url = await authController.getVideo(film.vodId!.toString(), 0);
                            Get.toNamed('/film', arguments: {'url': url, 'vodId': film.vodId!.toString()});
                          }
                        },
                        child: Container(
                          width: MediaQuery.of(context).size.width,
                          margin: EdgeInsets.symmetric(horizontal: 8.0),
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(12),
                          ),
                          child: ClipRRect(
                            borderRadius: BorderRadius.circular(12),
                            child: CachedNetworkImage(
                              imageUrl: film.vodPicThumb ?? '',
                              fit: BoxFit.cover,
                              placeholder: (context, url) => Container(
                                color: Colors.grey[200],
                              ),
                              errorWidget: (context, url, error) => const Icon(Icons.error), // 错误时显示
                            ),
                          ),
                        ),
                      );
                    }).toList(),
                  ),
                ),
                // 圆点指示器
                Container(
                  margin: EdgeInsets.only(right: 20, bottom: 10),
                  padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                  decoration: BoxDecoration(
                    color: Colors.black54,
                    borderRadius: BorderRadius.circular(10),
                  ),
                  child: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: homeController.carouselFilmList.asMap().entries.map((entry) {
                      return Container(
                        width: 8.0,
                        height: 8.0,
                        margin: EdgeInsets.symmetric(horizontal: 2.0),
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          color: _currentIndex == entry.key ? Colors.white : Colors.white.withOpacity(0.5),
                        ),
                      );
                    }).toList(),
                  ),
                ),
              ],
            ),
            SizedBox(height: 10),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                SizedBox(width: 10),
                Expanded(
                  child: _buildItem(
                    '全部',
                    'assets/images/all.png',
                    () => Get.toNamed('/filmAll'),
                  ),
                ),
                SizedBox(width: 10),
                Expanded(
                  child: _buildItem(
                    '榜单',
                    'assets/images/top.png',
                    () => Get.toNamed('/filmRank'),
                  ),
                ),
                SizedBox(width: 10),
                Expanded(
                  child: _buildItem(
                    '时间表',
                    'assets/images/top.png',
                    () => Get.toNamed('/filmWeek'),
                  ),
                ),
                SizedBox(width: 10),
                Expanded(
                  child: _buildItem(
                    '追番',
                    'assets/images/top.png',
                    () => authController.checkToken('/followFilm'),
                  ),
                ),
                SizedBox(width: 10),
              ],
            ),
            SizedBox(height: 10),
            _buildWeek(),
            _buildRecommend(),
            // _buildMouthTop(),
            Container(
              height: 100,
              alignment: Alignment.center,
              child: Text('--我是有底线的--'),
            )
          ],
        ),
      ),
    );
  }

  Widget _buildWeek() {
    final Map<int, String> indexToDayName = {
      1: '周一',
      2: '周二',
      3: '周三',
      4: '周四',
      5: '周五',
      6: '周六',
      7: '周日',
    };
    final Map<String, RxList<Film>> weeklySchedule = {
      '周一': homeController.mondayFilmList,
      '周二': homeController.tuesdayFilmList,
      '周三': homeController.wednesdayFilmList,
      '周四': homeController.thursdayFilmList,
      '周五': homeController.fridayFilmList,
      '周六': homeController.saturdayFilmList,
      '周日': homeController.sundayFilmList,
    };
    return Container(
      margin: const EdgeInsets.only(top: 10.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const Text(
                  '排期表',
                  style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: Colors.pink,
                  ),
                ),
                GestureDetector(
                  onTap: () => Get.toNamed('/filmWeek'),
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
                    decoration: BoxDecoration(
                      color: Colors.pink[400],
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: const Text(
                      '更多',
                      style: TextStyle(color: Colors.white, fontSize: 13),
                    ),
                  ),
                ),
              ],
            ),
          ),
          const SizedBox(height: 15),
          SizedBox(
            height: 30,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              physics: const BouncingScrollPhysics(),
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              itemCount: indexToDayName.length,
              itemBuilder: (context, index) {
                final dayIndex = index + 1;
                final dayName = indexToDayName[dayIndex]!;
                return Obx(() {
                  final isSelected = homeController.selectedDayIndex.value == dayIndex;
                  return GestureDetector(
                    onTap: () {
                      homeController.selectedDayIndex.value = dayIndex;
                    },
                    child: Container(
                      padding: const EdgeInsets.symmetric(horizontal: 16.0),
                      alignment: Alignment.center,
                      child: Text(
                        dayName,
                        style: TextStyle(
                          fontSize: 15,
                          fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
                          color: isSelected ? Colors.pink[400] : Colors.grey[400],
                        ),
                      ),
                    ),
                  );
                });
              },
            ),
          ),
          const SizedBox(height: 10),
          Obx(() {
            if (weeklySchedule.values.every((list) => list.isEmpty)) {
              return const SizedBox(
                height: 220,
                child: Center(child: CircularProgressIndicator(strokeWidth: 2.0)),
              );
            }
            final selectedDayName = indexToDayName[homeController.selectedDayIndex.value]!;
            final filmList = weeklySchedule[selectedDayName] ?? [];
            if (filmList.isEmpty) {
              return const SizedBox(
                height: 220,
                child: Center(
                  child: Text(
                    '今天没有更新哦～',
                    style: TextStyle(color: Colors.grey),
                  ),
                ),
              );
            }
            return SizedBox(
              height: 240,
              child: ListView.builder(
                scrollDirection: Axis.horizontal,
                physics: const BouncingScrollPhysics(),
                padding: const EdgeInsets.only(left: 16.0),
                itemCount: filmList.length,
                itemBuilder: (context, index) {
                  return _buildFilmPosterItem(filmList[index]);
                },
              ),
            );
          }),
        ],
      ),
    );
  }

  Widget _buildFilmPosterItem(Film film) {
    final String cornerTagText = film.vodYear != null ? '${film.vodYear}年${film.vodLang ?? ''}月' : '';
    return GestureDetector(
      onTap: () async {
        bool isLogin = await authController.check();
        if (isLogin) {
          String url = await authController.getVideo(film.vodId!.toString(), 0);
          Get.toNamed('/film', arguments: {'url': url, 'vodId': film.vodId!.toString()});
        }
      },
      child: Container(
        width: 130,
        margin: const EdgeInsets.only(right: 12.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Stack(
              children: [
                ClipRRect(
                  borderRadius: BorderRadius.circular(8.0),
                  child: Image.network(
                    film.vodPic ?? '',
                    width: 130,
                    height: 180,
                    fit: BoxFit.cover,
                    errorBuilder: (context, error, stack) => Container(
                      width: 130,
                      height: 180,
                      decoration: BoxDecoration(
                        color: Colors.grey[800],
                        borderRadius: BorderRadius.circular(8.0),
                      ),
                      child: Icon(
                        Icons.movie_creation_outlined,
                        color: Colors.grey[600],
                        size: 40,
                      ),
                    ),
                  ),
                ),
                Positioned(
                  top: 0,
                  right: 0,
                  child: Container(
                    padding: const EdgeInsets.symmetric(
                      horizontal: 6.0,
                      vertical: 3.0,
                    ),
                    decoration: BoxDecoration(
                      color: Colors.red.withOpacity(0.9),
                      borderRadius: const BorderRadius.only(
                        topRight: Radius.circular(8.0),
                        bottomLeft: Radius.circular(8.0),
                      ),
                    ),
                    child: Text(
                      cornerTagText,
                      style: const TextStyle(
                        color: Colors.white,
                        fontSize: 11,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 6),
            Text(
              film.vodName ?? '',
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: const TextStyle(
                color: Colors.black,
                fontSize: 14,
                fontWeight: FontWeight.w500,
              ),
            ),
            const SizedBox(height: 2),
            Text(
              film.vodRemarks ?? '未知',
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                color: Colors.grey[500],
                fontSize: 12,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildRecommend() {
    return Container(
      child: Column(
        children: [
          // 标题
          Container(
            padding: EdgeInsets.only(left: 12, bottom: 8),
            alignment: Alignment.centerLeft,
            child: Text(
              '站内推荐',
              style: TextStyle(
                fontSize: 16,
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
          // 网格布局
          Obx(
            () => GridView.count(
              shrinkWrap: true, // 让GridView适应Column内部
              physics: NeverScrollableScrollPhysics(), // 禁用独立滚动
              crossAxisCount: 4, // 每行4个
              childAspectRatio: 0.45, // 宽高比
              mainAxisSpacing: 10, // 行间距
              crossAxisSpacing: 8, // 列间距
              padding: EdgeInsets.symmetric(horizontal: 12),
              children: homeController.recommendFilmList.map((film) {
                // 生成8个项
                return GestureDetector(
                  onTap: () async {
                    bool isLogin = await authController.check();
                    if (isLogin) {
                      String url = await authController.getVideo(film.vodId!.toString(), 0);
                      Get.toNamed('/film', arguments: {'url': url, 'vodId': film.vodId!.toString()});
                    }
                  },
                  child: _buildRecommendItem(
                    film.vodName ?? '',
                    film.vodPicThumb ?? '',
                    film.vodRemarks ?? '',
                  ),
                );
              }).toList(),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildRecommendItem(String title, String imagePath, String status) {
    return Column(
      children: [
        Stack(
          children: [
            ClipRRect(
              borderRadius: BorderRadius.circular(10),
              child: CachedNetworkImage(
                imageUrl: imagePath, // 网络图片URL
                width: 120,
                height: 160,
                fit: BoxFit.cover,
                placeholder: (context, url) => Container(
                  width: 120,
                  height: 160,
                  color: Colors.grey[200], // 加载时的占位背景色
                ),
                errorWidget: (context, url, error) => Container(
                  width: 120,
                  height: 160,
                  color: Colors.grey[300],
                  child: const Icon(Icons.error_outline, color: Colors.red), // 错误时显示图标
                ),
              ),
            ),
            // Positioned(
            //   top: 0,
            //   left: 0,
            //   child: Container(
            //     padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), // 文字内边距
            //     decoration: BoxDecoration(
            //       color: Colors.green, // 绿色背景
            //       borderRadius: BorderRadius.only(
            //         topLeft: Radius.circular(8),
            //         bottomRight: Radius.circular(8),
            //       ),
            //     ),
            //     child: Text(
            //       score,
            //       style: TextStyle(
            //         color: Colors.white, // 白色文字
            //         fontSize: 10, // 文字大小
            //       ),
            //     ),
            //   ),
            // ),
            Positioned(
              bottom: 0,
              right: 0,
              child: Container(
                padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                child: Text(
                  status,
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 10,
                  ),
                ),
              ),
            ),
          ],
        ),
        SizedBox(height: 8),
        Container(
          child: Text(
            title,
            overflow: TextOverflow.ellipsis,
            maxLines: 1,
            style: TextStyle(
              fontSize: 10,
            ),
          ),
        )
      ],
    );
  }

  Widget _buildItem(
    String title,
    String imagePath,
    VoidCallback onTap,
  ) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        height: 30,
        width: double.infinity,
        //swidth: 150,
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage(imagePath),
            fit: BoxFit.cover,
          ),
          borderRadius: BorderRadius.circular(50),
        ),
        child: Center(
          child: Text(
            title,
            style: TextStyle(
              color: Colors.white,
              fontSize: 16,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildTabContent(String text) {
    return EasyRefresh(
      controller: _controller,
      header: const CupertinoHeader(
        position: IndicatorPosition.locator,
        safeArea: false,
      ),
      footer: const CupertinoFooter(
        position: IndicatorPosition.locator,
      ),
      onRefresh: () async {
        // 下拉刷新逻辑
        filmCategoryController.refreshData();
        _controller.finishRefresh();
        _controller.resetFooter();
      },
      onLoad: () async {
        // 上拉加载逻辑
        filmCategoryController.loadMoreData();
        _controller.finishLoad();
      },
      child: CustomScrollView(
        slivers: [
          // Sliver 1: 筛选区域
          // 使用 SliverToBoxAdapter 将一个普通的 Widget 转换为 Sliver
          SliverToBoxAdapter(
            child: _buildFilterArea(filmCategoryController),
          ),

          // Sliver 3: 影片网格
          // 如果列表为空，显示提示信息；否则，显示网格
          Obx(
            () => filmCategoryController.filmList.isEmpty
                ? SliverFillRemaining(
                    // 这个 Sliver 会填满剩余的空间
                    child: const Center(child: Text('没有找到相关影片')),
                  )
                : _buildFilmGridSliver(filmCategoryController),
          ), // 注意：方法名已更改
        ],
      ),
    );
  }

  /// 【新】构建筛选区域，替代旧的 FilterBar 和 DropdownMenu
  Widget _buildFilterArea(FilmCategoryController controller) {
    return Container(
      padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
      child: Column(
        // 遍历所有筛选类别，生成每一行筛选
        children: controller.filterCategories.map((category) {
          return _buildFilterRow(controller, category);
        }).toList(),
      ),
    );
  }

  /// 构建筛选区域中的每一行
  Widget _buildFilterRow(FilmCategoryController controller, FilterCategory category) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 6.0),
      child: Row(
        children: [
          // 固定的“全部”按钮（对于有“全部”选项的类别）
          if (category.options.contains('全部'))
            Obx(() => _buildFilterChip(
                  controller: controller,
                  categoryKey: category.key,
                  option: '全部',
                  // “全部”按钮的样式比较特殊
                  isSpecial: true,
                  isSelected: controller.selectedFilters[category.key] == '全部',
                )),

          // 右侧可横向滚动的部分
          Expanded(
            child: SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              // 去掉滚动条，如果你想显示，可以去掉下面这行
              physics: const BouncingScrollPhysics(),
              child: Row(
                children: category.options
                    .where((option) => option != '全部') // 排除“全部”选项
                    .map((option) {
                  return Padding(
                    padding: const EdgeInsets.only(left: 16.0), // 选项之间的间距
                    child: Obx(() => _buildFilterChip(
                          controller: controller,
                          categoryKey: category.key,
                          option: option,
                          isSelected: controller.selectedFilters[category.key] == option,
                        )),
                  );
                }).toList(),
              ),
            ),
          ),
        ],
      ),
    );
  }

  /// 构建单个筛选标签 (Chip)
  Widget _buildFilterChip({
    required FilmCategoryController controller,
    required String categoryKey,
    required String option,
    required bool isSelected,
    bool isSpecial = false, // 是否是特殊的“全部”按钮
  }) {
    return GestureDetector(
      onTap: () => controller.selectFilterOption(categoryKey, option),
      child: isSpecial
          ? Container(
              padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0),
              decoration: BoxDecoration(
                color: isSelected ? Colors.red.withOpacity(0.1) : const Color(0xFFF5F5F5),
                borderRadius: BorderRadius.circular(8.0),
              ),
              child: Text(
                option,
                style: TextStyle(
                  fontSize: 15,
                  color: isSelected ? Colors.red : Colors.black87,
                  fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
                ),
              ),
            )
          : Container(
              padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0),
              child: Text(
                option,
                style: TextStyle(
                  fontSize: 15,
                  color: isSelected ? Colors.red : Colors.black87,
                  fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
                ),
              ),
            ),
    );
  }

  /// 【核心改动】构建影片的网格布局，返回一个 SliverGrid
  Widget _buildFilmGridSliver(FilmCategoryController controller) {
    // 使用 SliverPadding 为网格添加内边距
    return Obx(
      () => SliverPadding(
        padding: const EdgeInsets.all(12.0),
        sliver: SliverGrid(
          // 定义网格布局
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            crossAxisSpacing: 12.0,
            mainAxisSpacing: 12.0,
            childAspectRatio: 2 / 3.5,
          ),
          // 定义如何构建网格中的每一个项目
          delegate: SliverChildBuilderDelegate(
            (context, index) {
              final film = controller.filmList[index];
              return _buildFilmCard(film);
            },
            childCount: controller.filmList.length,
          ),
        ),
      ),
    );
  }

  /// 构建单个影片卡片
  Widget _buildFilmCard(Film film) {
    return GestureDetector(
      onTap: () => authController.checkToken('/film', arguments: {'vodId': film.vodId}),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch, // 让子项水平方向上填充满
        children: [
          // 图片部分
          Expanded(
            child: ClipRRect(
              borderRadius: BorderRadius.circular(8.0),
              child: Stack(
                fit: StackFit.expand,
                children: [
                  Image.network(
                    film.vodPic ?? '',
                    fit: BoxFit.cover,
                    loadingBuilder: (context, child, progress) => progress == null ? child : const Center(child: CircularProgressIndicator(strokeWidth: 2.0)),
                    errorBuilder: (context, error, stack) => const Icon(Icons.broken_image, color: Colors.grey),
                  ),
                  Positioned(
                    bottom: 0,
                    left: 0,
                    right: 0,
                    child: Container(
                      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3),
                      decoration: BoxDecoration(
                        gradient: LinearGradient(
                          begin: Alignment.bottomCenter,
                          end: Alignment.topCenter,
                          colors: [Colors.black.withOpacity(0.7), Colors.transparent],
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
          // 标题部分
          const SizedBox(height: 6),
          Text(
            film.vodName ?? '',
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
            style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
          ),
        ],
      ),
    );
  }
}
